//给定一个非负整数 n ，请计算 0 到 n 之间的每个数字的二进制表示中 1 的个数，并输出一个数组。 
//
// 
//
// 示例 1: 
//
// 
//输入: n = 2
//输出: [0,1,1]
//解释: 
//0 --> 0
//1 --> 1
//2 --> 10
// 
//
// 示例 2: 
//
// 
//输入: n = 5
//输出: [0,1,1,2,1,2]
//解释:
//0 --> 0
//1 --> 1
//2 --> 10
//3 --> 11
//4 --> 100
//5 --> 101
// 
//
// 
//
// 说明 : 
//
// 
// 0 <= n <= 10⁵ 
// 
//
// 
//
// 进阶: 
//
// 
// 给出时间复杂度为 O(n*sizeof(integer)) 的解答非常容易。但你可以在线性时间 O(n) 内用一趟扫描做到吗？ 
// 要求算法的空间复杂度为 O(n) 。 
// 你能进一步完善解法吗？要求在C++或任何其他语言中不使用任何内置函数（如 C++ 中的 __builtin_popcount ）来执行此操作。 
// 
//
// 
//
// 
// 注意：本题与主站 338 题相同：https://leetcode-cn.com/problems/counting-bits/ 
//
// Related Topics 位运算 动态规划 👍 156 👎 0


package LeetCode.editor.cn;


import java.util.Objects;

/**
 * @author ldltd
 * @date 2025-01-08 19:29:32
 * @description LCR 003.比特位计数
 
 */
 
public class W3tCBm {
    public static void main(String[] args) {
    //测试代码
    W3tCBm fun = new W3tCBm();
    Solution solution= fun.new Solution();
    Long dasd=123L;
        System.out.println(!Objects.equals(null,dasd));
    }

//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    public int[] countBits1(int n) {
        int [] res=new int[n+1];
        for (int i = 0; i <=n; i++) {
            int t=0;
            int x=i;
            while (x!=0){
                x-=lowbit(x);
                t++;
            }
            res[i]=t;
        }
        return res;
    }
    // x & -x == x & (~x + 1)
    //x-(x&(x-1))三种
    private   int lowbit(int x){
        return x&-x;  //返回最后一位1
    }

    public int[] countBits2(int n) {
        int[] bits = new int[n + 1];
        for (int i = 0; i <= n; i++) {
            bits[i] = countOnes(i);
            //Integer.bitCount可以计算整数中二进制的1的个数
            //bits[i]=Integer.bitCount(i);
        }
        return bits;
    }
    /*对于任意整数，令x=x&(x-1)
    假设 x 是一个正整数，
    x - 1 的二进制会将从最低位开始的第一个 1 变为 0，
    而它右侧的所有位则变为 1。
    比如0100 4   变成 0011
    1100 12  变成 1011
     * 将x的二进制表示最后一个1变为0直到变成0*/
    public int countOnes(int x) {
        int ones = 0;
        while (x > 0) {
            x &= (x - 1);
            ones++;
        }
        return ones;
    }

    /*如果当前是奇数，则1的个数比前一个偶数多1
     * 如果当前是偶数，则等于他折半的数的个数（进位）*/
    public int[] countBits3(int n) {
        int [] res=new int[n+1];
        for (int i = 1; i <=n ; i++) {
            if(i%2==1){
                res[i]=res[i-1]+1;
            }else {
                res[i]=res[i/2];
            }
        }
        return res;
    }
    /*最高有效位*/
    public int[] countBits4(int n) {
        int[] bits = new int[n + 1];
        int highBit = 0;
        for (int i = 1; i <= n; i++) {
            /*如果一个数是2的整数次幂，
             * (i & (i - 1)等于0，
             * 每次计算到整数幂时更新highbit
             * i比i-highbit的计数多1（最高位）*/
            if ((i & (i - 1)) == 0) {
                highBit = i;
            }
            bits[i] = bits[i - highBit] + 1;
        }
        return bits;
    }

    /*最低有效位
     * 如果是偶数，等于x/2,
     * 如果是偶数，等于x/2+1*/
    public int[] countBits5(int n) {
        int [] dp=new int[n+1];
        for (int i = 1; i <=n; i++) {
            dp[i]=dp[i>>1]+(i&1);
        }
        return dp;
    }
    /*最低设置位
     * i的计数等于将i的最后一位变成0的计数+1
     * 即dp[i]=dp[x&(x-1)]+1*/
    public int[] countBits(int n) {
        int [] dp=new int[n+1];
        for (int i = 1; i <=n; i++) {
            dp[i] = dp[i & (i - 1)] + 1;
        }
        return dp;
    }

}
//leetcode submit region end(Prohibit modification and deletion)

}
